﻿#region Using References

using System;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reflection;

#endregion

namespace Beaker.Specs
{
	public static class Reflect
	{
		/// <summary>
		/// Gets the name of the property accessed by the lambda expression
		/// </summary>
		[Pure]
		public static string GetPropertyName<TSource, TProperty>( Expression<Func<TSource, TProperty>> propertyLambda )
		{
			Contract.Requires<ArgumentNullException>( propertyLambda != null );
			Contract.Requires<ArgumentException>( propertyLambda.Body is MemberExpression, "Expression must be property" );
			Contract.Requires<ArgumentException>( ( (MemberExpression)propertyLambda.Body ).Member is PropertyInfo, "Expression must be property" );

			return GetPropertyInfo( propertyLambda ).Name;
		}

		/// <summary>
		/// Gets the property-info of the property accessed by the lambda expression
		/// </summary>
		[Pure]
		public static PropertyInfo GetPropertyInfo<TSource, TProperty>( Expression<Func<TSource, TProperty>> propertyLambda )
		{
			Contract.Requires<ArgumentNullException>( propertyLambda != null );
			Contract.Requires<ArgumentException>( propertyLambda.Body is MemberExpression, "Expression must be property" );
			Contract.Requires<ArgumentException>( ( (MemberExpression)propertyLambda.Body ).Member is PropertyInfo, "Expression must be property" );

			return (PropertyInfo)( (MemberExpression)propertyLambda.Body ).Member;
		}
	}
}